BizQQWPA
		.define(
				"util.domain",
				function() {
					var domain = {}, dm = document.domain;
					try {
						domain.url = location.href
					} catch (e) {
						domain.url = ""
					}
					domain.topDomain = function() {
						var reg1 = /\.(?:(?:edu|gov|com|org|net)\.cn|co\.nz)$/, reg2 = /^[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d$/, slicePos = reg1
								.test(dm) ? -3 : reg2.test(dm) ? 0 : -2;
						return dm.split(".").slice(slicePos).join(".")
					}();
					domain.domain = function() {
						var reg = /(?::[\/]{2}|:[\\]{3})([a-zA-Z0-9_\.]+)/;
						try {
							var ret = reg.exec(domain.url);
							return ret ? ret[1] || dm : dm
						} catch (e) {
							return dm
						}
					}();
					return domain
				});
BizQQWPA
		.define(
				"wpa.wpaMgr",
				"globalSettings,lang.each,util.proxy,util.cookie,util.titleFlash,util.report,util.serialize,util.domain,wpa.WPA",
				function(require) {
					var globalSettings = require("globalSettings"), each = require("each"), proxy = require("proxy"), titleFlash = require("titleFlash"), report = require("report"), serialize = require("serialize"), domain = require("domain"), cookie = require("cookie"), WPA = require("WPA");
					var REPORT_POSSIBILITY = 40;
					var passRandom = function(poss) {
						var r = poss || 10;
						if (Math.random() * 100 <= r) {
							return true
						}
						return false
					};
					var reportWpa = function(url, opts) {
						if (passRandom(REPORT_POSSIBILITY)) {
							report(url + "?" + serialize(opts))
						}
					};
					var displayReport = function(params) {
						var url = "http://prom.b.qq.com/wpadisplay/r.gif?", optsArr = [
								"wty", "type", "nameAccount", "kfuin", "ws",
								"aty", "a", "title", "wording", "wording2" ], reportOpts = {
							version : globalSettings.version
						};
						each(
								optsArr,
								function() {
									reportOpts[this] = typeof params[this] === "undefined" ? ""
											: params[this]
								});
						report(url + serialize(reportOpts))
					};
					return {
						newWPA : function(params) {
							var nameAccount = params.nameAccount;
							if (!nameAccount) {
								return
							}
							displayReport(params);
							reportWpa(
									"http://report.b.qq.com/crmReport/accesslog",
									{
										FUID : cookie.get("pgv_pvi"),
										FKFUin : params.kfuin,
										FNa : params.nameAccount,
										FRurl : window.document.referrer
									});
							return new WPA(params)
						},
						invite : function(params, di) {
							var mgr = this, defaultInvite = function() {
								titleFlash.on("【您有新信息】");
								params.insert = function(node) {
									var body = document
											.getElementsByTagName("body")[0];
									body.insertBefore(node, body.firstChild)
								};
								mgr.newWPA(params)
							};
							if (!di) {
								defaultInvite();
								return
							}
							try {
								var chat = proxy({
									params : params
								}, WPA.prototype.launchChat);
								window[di] && window[di](chat, params["msg"])
							} catch (e) {
								defaultInvite()
							}
						}
					}
				});
BizQQWPA
		.define(
				"wpa.visitor",
				"lang.browser,util.log,util.speedReport,util.getJSONP,util.domain,util.pubSub,wpa.filter,wpa.ta,wpa.invite,wpa.wpaMgr,wpa.ta,wpa.kfuin",
				function(require) {
					var invite = require("invite"), domain = require("domain"), filter = require("filter"), getJSONP = require("getJSONP"), pubSub = require("pubSub"), log = require("log"), speedReport = require("speedReport"), ta = require("ta"), kfuinCahe = require("kfuin"), browser = require("browser");
					var CRM_BLOCK_ON_SERVERSIDE = 1;
					var GET_CONFIG_URL = "http://visitor.crm2.qq.com/cgi/visitorcgi/ajax/wpa_first_heart_beat.php";
					return function(config) {
						var nameAccount = config.nameAccount;
						if (!nameAccount || nameAccount === "undefined") {
							return
						}
						if (invite.isLoaded(nameAccount) || !filter.TA) {
							return
						}
						var uid, cfg, launch = function(uid, cfg) {
							if (!uid || !cfg) {
								return
							}
							if (cfg.block === CRM_BLOCK_ON_SERVERSIDE) {
								return
							}
							if (browser && browser.ua) {
								var spiderReg = /spider|bot|^\s*$/;
								if (spiderReg.test(browser.ua)) {
									return
								}
							}
							if (filter.CRM) {
								cfg.di = config.di;
								cfg.kfuin = config.kfuin;
								log(nameAccount + " try launch slave");
								invite.load(nameAccount, uid, cfg)
							}
						};
						pubSub.one("TA.loaded", function(data) {
							uid = data;
							launch(uid, cfg)
						});
						pubSub.one("Invite.first", function(data) {
							cfg = data;
							launch(uid, cfg)
						});
						ta(nameAccount, domain.topDomain, function(uid) {
							pubSub.pub("TA.loaded", uid)
						});
						var opts = {
							nameAccount : nameAccount,
							dm : domain.topDomain,
							title : document.title,
							url : location.href.split("://")[1].split("?")[0]
						};
						getJSONP(GET_CONFIG_URL, opts, function(cfg) {
							pubSub.pub("Invite.first", cfg)
						});
						config.kfuin
								&& kfuinCahe.set(nameAccount, config.kfuin)
					}
				});
BizQQWPA.define("wpa.kfuin", "util.getJSONP", function(require) {
	var getJSONP = require("getJSONP");
	var GET_KFUIN_URL = "http://wpl.b.qq.com/cgi/conv.php";
	var kfuins = {};
	return {
		get : function(nameAccount, callback) {
			callback = callback || function() {
			};
			if (!nameAccount || kfuins[nameAccount]) {
				callback(kfuins[nameAccount]);
				return
			}
			var opts = {
				num : nameAccount
			};
			getJSONP(GET_KFUIN_URL, opts, function(rs) {
				if (!rs || rs.r !== 0) {
					callback();
					return
				}
				var kfuin = kfuins[nameAccount] = rs.data.kfuin;
				callback(kfuin)
			})
		},
		set : function(nameAccount, kfuin) {
			kfuins[nameAccount] = kfuin
		}
	}
});
BizQQWPA.define("util.proxy", function() {
	return function(ns, fn) {
		return function() {
			return fn.apply(ns, arguments)
		}
	}
});
BizQQWPA.define("util.titleFlash", "util.taskMgr", function(require) {
	var TITLE_FLASH_GAP = 120;
	var taskMgr = require("taskMgr");
	var doc = document, title = doc.title, task = taskMgr.newTask(function() {
		var t = doc.title;
		doc.title = t.substr(1, t.length) + t.substr(0, 1)
	}, TITLE_FLASH_GAP);
	return titleFlash = {
		on : function(msg) {
			doc.title = msg + ("" + doc.title);
			task.run()
		},
		off : function() {
			task.pause();
			doc.title = title
		}
	}
});
BizQQWPA.define("util.cookie", function() {
	var doc = document;
	return {
		set : function(name, value, domain, path, expires) {
			if (expires) {
				expires = new Date(+new Date + expires)
			}
			var tempcookie = name + "=" + escape(value)
					+ (expires ? "; expires=" + expires.toGMTString() : "")
					+ (path ? "; path=" + path : "")
					+ (domain ? "; domain=" + domain : "");
			if (tempcookie.length < 4096) {
				doc.cookie = tempcookie
			}
		},
		get : function(name) {
			var carr = doc.cookie.match(new RegExp("(^| )" + name
					+ "=([^;]*)(;|$)"));
			if (carr != null) {
				return unescape(carr[2])
			}
			return null
		},
		del : function(name, domain, path) {
			if (this.get(name)) {
				doc.cookie = name + "=" + (path ? "; path=" + path : "")
						+ (domain ? "; domain=" + domain : "")
						+ ";expires=Thu, 01-Jan-1970 00:00:01 GMT"
			}
		},
		find : function(pattern) {
			return doc.cookie.match(pattern).split(",")
		}
	}
});
BizQQWPA
		.define(
				"wpa.WPA",
				"globalSettings,lang.browser,util.cookie,lang.typeEnhance,util.serialize,util.proxy,util.pad,util.Bits,util.getScript,util.getJSONP,util.domain,util.events,util.onLoad,util.offset,util.report,util.log,util.speedReport,wpa.SelectPanel,util.onIframeLoaded,util.GUID,wpa.getQQVersion,wpa.ViewHelper,wpa.views,wpa.ta,wpa.kfuin,wpa.sid",
				function(require) {
					var globalSettings = require("globalSettings"), proxy = require("proxy"), typeEnhance = require("typeEnhance"), pad = require("pad"), Bits = require("Bits"), getScript = require("getScript"), getJSONP = require("getJSONP"), domain = require("domain"), events = require("events"), onLoad = require("onLoad"), serialize = require("serialize"), browser = require("browser"), offset = require("offset"), report = require("report"), log = require("log"), speedReport = require("speedReport"), GUID = require("GUID"), SelectPanel = require("SelectPanel"), onIframeLoaded = require("onIframeLoaded"), getQQVersion = require("getQQVersion"), ViewHelper = require("ViewHelper"), views = require("views"), ta = require("ta"), kfuinCache = require("kfuin"), cookie = require("cookie"), sidCache = require("sid");
					var global = window;
					var WPA_TYPE_TA_INVITE_ONLY = "0", WPA_TYPE_NORMAL = "1", WPA_TYPE_LINK = "2", WPA_TYPE_CUSTOM = "3", SESSION_VERSION_TA = "4", WPA_STYLE_TYPE_INVITE = "20", APPOINTED_TYPE_AUTO = "0", APPOINTED_TYPE_KFEXT = "1", APPOINTED_TYPE_GROUP = "2", WPA_FLOAT_TYPE_FIXED = "0", WPA_FLOAT_TYPE_SCROLL = "1", WPA_FLOAT_POSITION_X_LEFT = "0", WPA_FLOAT_POSITION_X_CENTER = "1", WPA_FLOAT_POSITION_X_RIGHT = "2", WPA_FLOAT_POSITION_Y_TOP = "0", WPA_FLOAT_POSITION_Y_CENTER = "1", WPA_FLOAT_POSITION_Y_BOTTOM = "2", IS_INVITE_WPA_FALSE = "0", IS_INVITE_WPA_TRUE = "1", CHAT_TYPE_AIO = 1, CHAT_TYPE_ANONYMOUS = 2;
					var SPEED_REPORT_DISPLAY = .1, REPORT_POSSIBILITY = 40;
					var passRandom = function(poss) {
						var r = poss || 10;
						if (Math.random() * 100 <= r) {
							return true
						}
						return false
					};
					var reportWpa = function(url, opts) {
						if (passRandom(REPORT_POSSIBILITY)) {
							report(url + "?" + serialize(opts))
						}
					};
					var WPA = function(params) {
						this.params = params;
						this.insert = params.insert;
						this.wty = params.wty;
						var self = this, nameAccount = this.nameAccount = params.nameAccount, kfuin = this.kfuin = params.kfuin;
						switch (this.wty) {
						case WPA_TYPE_NORMAL:
							this.render();
							break;
						case WPA_TYPE_CUSTOM:
							this.custom()
						}
						!this.kfuin
								&& kfuinCache.get(nameAccount, function(data) {
									data && (self.kfuin = data)
								});
						!this.sid && sidCache.get(nameAccount, function(data) {
							data && (self.sid = data)
						});
						report("http://prom.b.qq.com/se/r.gif?na="
								+ nameAccount + "&ref="
								+ encodeURIComponent(document.referrer))
					};
					WPA.prototype = {
						render : function() {
							var params = this.params;
							var width, height, type = parseInt(params["type"]), typeStr, isFloat = false;
							switch (type) {
							case 1:
								typeStr = "a01";
								width = 92;
								height = 22;
								break;
							case 2:
								typeStr = "a02";
								width = 77;
								height = 22;
								break;
							case 10:
								typeStr = "b01";
								width = 93;
								height = 151;
								isFloat = true;
								break;
							case 11:
								typeStr = "b02";
								width = 327;
								height = 172;
								isFloat = true;
								break;
							case 12:
								typeStr = "b03";
								width = 121;
								height = 277;
								isFloat = true;
								break;
							case 20:
								typeStr = "i01";
								width = 327;
								height = 172;
								isFloat = true;
								break;
							case 30:
								typeStr = "d01";
								width = params["txw"];
								height = params["txh"];
								isFloat = true;
								break
							}
							this.type = typeStr;
							this.width = width;
							this.height = height;
							this.createWPA();
							if (type > 9 && type < 14 || type === 20
									|| type === 30) {
								this.initFloatWPA()
							}
						},
						createWPA : function() {
							var speedRpt = speedReport("7818", "21", "1");
							var wpa = this, type = this.type, width = this.width, height = this.height, view = views[type];
							var iframe;
							try {
								iframe = document
										.createElement('<iframe scrolling="no" frameborder="0" width="'
												+ width
												+ '" height="'
												+ height
												+ '" allowtransparency="true" src="about:blank"></iframe>')
							} catch (e) {
								iframe = document.createElement("iframe");
								iframe.width = width;
								iframe.height = height;
								iframe.setAttribute("scrolling", "no");
								iframe.setAttribute("frameborder", 0);
								iframe.setAttribute("allowtransparency", true);
								iframe.setAttribute("src", "about:blank")
							}
							this.node = iframe;
							this.insert(iframe);
							if (browser.msie) {
								try {
									var accessTest = iframe.contentWindow.document
								} catch (e) {
									iframe.src = "javascript:void((function(){document.open();document.domain='"
											+ document.domain
											+ "';document.close()})())"
								}
							}
							var loaded = function() {
								var iWin = iframe.contentWindow, iDoc = iframe.contentDocument
										|| iWin.document;
								iDoc.open();
								iDoc
										.write([
												'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
												'<html xmlns="http://www.w3.org/1999/xhtml">',
												"<head>",
												'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
												browser.msie
														&& iframe.src !== "about:blank" ? "<script>document.domain='"
														+ document.domain
														+ "';</script>"
														: "", "</head>",
												"<body>", view.templ,
												"</body>", "</html>" ].join(""));
								iDoc.close();
								var helper = new ViewHelper(iDoc, wpa);
								view.init(iDoc, helper);
								var point = 1;
								speedRpt.addPoint(point).send(
										SPEED_REPORT_DISPLAY)
							};
							onIframeLoaded(iframe, loaded)
						},
						initFloatWPA : function() {
							var doc = window.document, params = this.params, type = parseInt(params["type"]), node = this.node, width = this.width, height = this.height;
							node.style.cssText = [
									"display:none;",
									"position:absolute;",
									type === 20 ? "z-index:2147483647!important;"
											: "z-index:2147483646!important;" ]
									.join(" ");
							onLoad(initIframeLoad);
							function initIframeLoad() {
								var isty = node.style, isIE = browser.msie, ver = parseInt(
										browser.version, 10), isQuirk = doc.compatMode === "BackCompat";
								isty.position = parseInt(params["fsty"], 10) == 0 ? "fixed"
										: "absolute";
								if (parseInt(params["fposX"]) == 0) {
									isty.left = 8 + "px";
									isty.right = "auto";
									isty.marginLeft = 0
								} else if (parseInt(params["fposX"]) == 1) {
									isty.left = "50%";
									isty.right = "auto";
									isty.marginLeft = "-" + parseInt(width / 2)
											+ "px"
								} else {
									isty.left = "auto";
									isty.right = 8 + "px";
									isty.marginLeft = 0
								}
								if (parseInt(params["fposY"]) == 0) {
									isty.top = 8 + "px";
									isty.bottom = "auto";
									isty.marginTop = 0
								} else if (parseInt(params["fposY"]) == 1) {
									isty.top = "50%";
									isty.bottom = "auto";
									isty.marginTop = "-" + parseInt(height / 2)
											+ "px"
								} else {
									isty.top = "auto";
									isty.bottom = 8 + "px";
									isty.marginTop = 0
								}
								if (isIE & ver < 7 || isQuirk) {
									isty.position = "absolute";
									if (parseInt(params["fsty"]) == 0) {
										isty.marginTop = 0;
										var itop;
										if (parseInt(params["fposY"]) == 0) {
											itop = 8
										} else if (parseInt(params["fposY"]) == 1) {
											itop = (offset.getClientHeight(doc) - height) / 2
										} else {
											itop = offset.getClientHeight(doc)
													- height - 8
										}
										setInterval(function() {
											isty.top = offset.getScrollTop(doc)
													+ itop + "px"
										}, 128)
									}
								}
								isty.display = "block"
							}
						},
						custom : function() {
							events.addEvent(this.params.node, "click", proxy(
									this, this.launchChat))
						},
						remove : function() {
							var node = this.node;
							node.parentNode.removeChild(node)
						},
						launchChat : function(callback) {
							var wpa = this, sptReport = speedReport("7818",
									"21", "2"), chatType = this.params.chatType;
							reportWpa(
									"http://report.b.qq.com/crmReport/clicklog",
									{
										FUID : cookie.get("pgv_pvi"),
										FKFUin : wpa.params.kfuin,
										FNa : wpa.params.nameAccount,
										FRurl : global.document.referrer
									});
							if (browser.isIOS || browser.isAndroid) {
								this.launchMobileChat();
								return
							}
							if (chatType == CHAT_TYPE_ANONYMOUS) {
								wpa.launchAnonymousChat(callback);
								return
							}
							if (chatType == CHAT_TYPE_AIO) {
								wpa.launchAIOChat(callback);
								return
							}
							!browser.msie && wpa.launchAIOChat(callback);
							getQQVersion(function(version) {
								sptReport.addPoint(7).send();
								if (version) {
									browser.msie && wpa.launchAIOChat(callback);
									return
								}
								new SelectPanel({
									onAIOChat : function() {
										wpa.launchAIOChat(callback)
									},
									onAnonyChat : function() {
										wpa.launchAnonymousChat(callback)
									}
								})
							})
						},
						launchMobileChat : function() {
							var nameAccount = this.params.nameAccount;
							kfuinCache
									.get(
											nameAccount,
											function(kfuin) {
												if (navigator.userAgent
														.indexOf("MicroMessenger") > -1
														&& domain.domain
																.indexOf("qq.com") === -1) {
													location.href = "http://wpd.b.qq.com/page/info.php?nameAccount="
															+ nameAccount;
													return
												}
												launch(schema(), fallback);
												function schema() {
													var dm = domain.domain, type = "crm";
													if (browser.isQQ
															&& browser.QQVersion === "4.5") {
														type = "wpa"
													}
													return browser.isAndroid
															&& browser.chrome
															&& parseInt(
																	browser.version,
																	10) > 25 ? "intent://im/chat?chat_type="
															+ type
															+ "&uin="
															+ kfuin
															+ "&version=1&src_type=web&web_src="
															+ location.protocol
															+ "://"
															+ dm
															+ "#Intent;scheme=mqqwpa;action=android.intent.action.VIEW;end"
															: "mqqwpa://im/chat?chat_type="
																	+ type
																	+ "&uin="
																	+ kfuin
																	+ "&version=1&src_type=web&web_src="
																	+ location.protocol
																	+ "://"
																	+ dm
												}
												function launch(schema, fail) {
													var start = +new Date;
													location.href = schema;
													setTimeout(function() {
														var gap = +new Date
																- start;
														if (gap < 1e3) {
															fail && fail()
														}
													}, 800)
												}
												function fallback() {
													location.href = "http://wpd.b.qq.com/page/info.php?nameAccount="
															+ nameAccount
												}
											})
						},
						launchAIOChat : function() {
							var iframe = document.createElement("iframe"), body = document
									.getElementsByTagName("body")[0];
							iframe.style.display = "none";
							body.insertBefore(iframe, body.firstChild);
							return function(callback) {
								var params = this.params, kfuin = this.kfuin, opts = {
									na : params.nameAccount,
									kfuin : kfuin,
									aty : params.aty,
									a : params.a,
									sid : this.sid,
									uid : ta.uid,
									url : domain.url,
									title : document.title,
									dm : domain.topDomain,
									clkSrc : params.clkSrc || "",
									ext : params.ext || ""
								}, guid = GUID();
								var sptReport = speedReport("7818", "21", "2");
								getJSONP(
										"http://wpd.b.qq.com/cgi/get_sign.php",
										opts,
										function(rs) {
											if (!rs || rs.r !== 0 || !rs.data) {
												return
											}
											iframe.src = rs.data.sign;
											var isLoaded = false, loaded = function() {
												if (isLoaded) {
													return
												}
												isLoaded = true;
												var clickId = rs.data.clkID;
												sptReport.addPoint(5).send();
												report("http://promreport.crm2.qq.com/wpaclick/r.gif?ty=1&kfuin="
														+ kfuin
														+ "&version="
														+ globalSettings.version
														+ "&browser="
														+ encodeURIComponent(navigator.userAgent)
														+ "&bfrom=1&appointType="
														+ params.aty
														+ "&appoint="
														+ params.a
														+ "&clkID="
														+ clickId
														+ "&guid="
														+ guid);
												global.taClick
														&& global.taClick(
																clickId,
																"clickid");
												typeEnhance
														.isFunction(callback)
														&& setTimeout(
																function() {
																	callback(params)
																}, 1e3)
											};
											onIframeLoaded(iframe, loaded);
											if (browser.msie) {
												var fallback = function() {
													setTimeout(
															function() {
																if (isLoaded) {
																	return
																}
																/interactive/
																		.test(iframe.readyState) ? loaded()
																		: fallback()
															}, 500)
												};
												fallback()
											}
										});
								report("http://promreport.crm2.qq.com/wpaclickorg/r.gif?kfuin="
										+ kfuin
										+ "&version="
										+ globalSettings.version
										+ "&browser="
										+ encodeURIComponent(navigator.userAgent)
										+ "&bfrom=1&appointType="
										+ params.aty
										+ "&appoint="
										+ params.a
										+ "&guid="
										+ guid)
							}
						}(),
						launchAnonymousChat : function(callback) {
							var params = this.params, sptReport = speedReport(
									"7818", "21", "2"), url = "http://wpd.b.qq.com/page/webchat.html?nameAccount="
									+ this.nameAccount, opener = window
									.open(
											url,
											"_blank",
											"height=516, width=598,toolbar=no,scrollbars=no,menubar=no,status=no,location=no");
							typeEnhance.isFunction(callback)
									&& callback(params);
							report("http://promreport.crm2.qq.com/wpaclick/r.gif?ty=2&kfuin="
									+ this.kfuin
									+ "&version="
									+ globalSettings.version
									+ "&browser="
									+ encodeURIComponent(navigator.userAgent)
									+ "&bfrom=1&appointType="
									+ params.aty
									+ "&appoint=" + params.a);
							opener.onload = function() {
								sptReport.addPoint(6).send()
							}
						}
					};
					return WPA
				});
BizQQWPA.define("util.getJSONP", "util.getScript,util.serialize", function(
		require) {
	var getScript = require("getScript"), serialize = require("serialize");
	var count = 0;
	return function(url, options, callback) {
		var fnName = "JSONP_CALLBACK_" + ++count + "_"
				+ Math.round(Math.random() * 100), script;
		options.cb = fnName;
		url += url.indexOf("?") === -1 ? "?" : "&";
		url += serialize(options);
		script = getScript(url);
		window[fnName] = function(json) {
			callback(json);
			setTimeout(function() {
				window[fnName] = null;
				script.parentNode.removeChild(script)
			}, 1)
		}
	}
});
BizQQWPA
		.define(
				"wpa.filter",
				"util.domain",
				function(require) {
					var TA_BLACKLIST = "", CRM_BLACKLIST = "qq.com,pengyou.com,qzoneapp.com,nipic.com,docin.com,51zxw.net,2155.com,xd.com,yto.net.cn,c-c.com,27.cn,05wan.com,alivv.cn,gogo.com,doctorjob.com.cn,emoney.cn,m4.cn,chinaktv.net,yk988.com,bangkaow.com,wsxsp.com,55tools.com,youxi518.com", CRM_WHITELIST = "b.qq.com,sales.b.qq.com,guilin.house.qq.com,ta.qq.com,hn.qq.com,nantong.house.qq.com";
					var domain = require("domain");
					return {
						TA : function() {
							var dm = domain.topDomain, IPReg = /^[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d$/, LocalReg = /^localhost$/, previewPageReg = /^wpa\.b\.qq\.com/;
							return TA_BLACKLIST.indexOf(dm) === -1
									&& !IPReg.test(dm) && !LocalReg.test(dm)
									&& !previewPageReg.test(domain.domain)
						}(),
						CRM : function() {
							try {
								var reg = new RegExp("(^|,)" + domain.domain);
								if (reg.test(CRM_WHITELIST)) {
									return true
								}
								var dm = domain.topDomain, dmReg = new RegExp(
										"(^|,)" + dm), IPReg = /^[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d\.[12]?\d?\d$/, LocalReg = /^localhost$/;
								return !dmReg.test(CRM_BLACKLIST)
										&& !IPReg.test(dm)
										&& !LocalReg.test(dm)
							} catch (e) {
							}
						}()
					}
				});
BizQQWPA
		.define(
				"wpa.ta",
				"util.getScript,util.serialize,util.cookie",
				function(require) {
					var URL = "http://tajs.qq.com/crmqq.php", UID_COOKIE_NAME = "pgv_pvi";
					var getScript = require("getScript"), serialize = require("serialize"), cookie = require("cookie");
					var loaded = false;
					var ta = function(nameAccount, domain, callback) {
						var isTriggered = false;
						if (ta.uid) {
							callback(ta.uid);
							isTriggered = true
						}
						if (!loaded) {
							var options = {
								uid : nameAccount,
								dm : domain
							}, url = URL + "?" + serialize(options, "=", "&");
							getScript(url, function() {
								loaded = true;
								if (isTriggered) {
									return
								}
								ta.uid = cookie.get(UID_COOKIE_NAME);
								if (ta.uid) {
									callback(ta.uid)
								} else {
									setTimeout(arguments.callee, 30)
								}
							})
						}
					};
					ta.uid = cookie.get(UID_COOKIE_NAME) || "";
					return ta
				});
BizQQWPA
		.define(
				"wpa.invite",
				"util.log,util.getJSONP,util.proxy,util.domain,util.blockStorage,util.taskMgr,wpa.wpaMgr",
				function(require) {
					var MASTER_MONITOR_GAP = 2e3, INVITE_MONITOR_GAP = 1e3, MASTER_HEATBEAT_GAP = 2e3, SLAVE_HEARTBEAT_GAP = 2e3, SERVER_MONITOR_GAP_MIN = 5e3, SERVER_MONITOR_GAP_MAX = 15e3, SERVER_MONITOR_SLEEPCHECK_GAP = 36e5, SERVER_MONITOR_SLEEPING_GAP = 1e3;
					var INVITE_SIGNAL = "is", INVITE_KFEXT = "ik", INVITE_MSG = "msg", MASTER_HEARTBEATS = "mh", MASTER_ID = "mid", SLAVE_IDS = "slid";
					var INVITE_SIGNAL_UNINVITED = "0", INVITE_SIGNAL_INVITE = "1", INVITE_SIGNAL_INVITED = "2", INVITE_KFEXT_AUTO = "0", MASTER_HEARTBEATS_ERROR = "-1", DATA_SEPERATOR = "|";
					var HEARTBEAT_URL = "http://visitor.crm2.qq.com/cgi/visitorcgi/ajax/wpa_heart_beat.php", CONFIRM_AUTO_INVITE_URL = "http://visitor.crm2.qq.com/cgi/visitorcgi/ajax/auto_invite.php";
					var RESULT_SUCCESS = 0, INVITE_STATE_UNINVITED = "0", INVITE_STATE_INVITE = "1", INVITE_STATE_INVITED = "2", AUTO_INVITE_TRUE = 1;
					var WPA_TYPE_TA_INVITE_ONLY = "0", WPA_TYPE_NORMAL = "1", WPA_TYPE_LINK = "2", SESSION_VERSION_TA = "4", WPA_STYLE_TYPE_INVITE = "20", APPOINTED_TYPE_AUTO = "0", APPOINTED_TYPE_KFEXT = "1", APPOINTED_TYPE_GROUP = "2", APPOINTED_TYPE_AUTO_INVITE = "4", APPOINTED_TYPE_INVITE = "5";
					var WPA_FLOAT_TYPE_FIXED = "0", WPA_FLOAT_POSITION_Y_CENTER = "1", WPA_FLOAT_POSITION_X_CENTER = "1", IS_INVITE_WPA_FALSE = "0", IS_INVITE_WPA_TRUE = "1";
					var log = require("log"), getJSONP = require("getJSONP"), proxy = require("proxy"), domain = require("domain"), blockStorage = require("blockStorage"), taskMgr = require("taskMgr"), wpaMgr = require("wpaMgr");
					var Slave = function(nameAccount, uid, cfg) {
						this.nameAccount = nameAccount;
						this.uid = uid;
						this.config = cfg;
						this.genID();
						this.storage = blockStorage(nameAccount);
						this.monitors = {
							master : taskMgr.newTask(
									proxy(this, this.masterMonitor),
									MASTER_MONITOR_GAP).run(),
							invite : taskMgr.newTask(
									proxy(this, this.inviteMonitor),
									INVITE_MONITOR_GAP).run()
						};
						this.heartBeat = taskMgr.newTask(
								proxy(this, this.heartBeatProcess),
								SLAVE_HEARTBEAT_GAP).run();
						this.setActive();
						window.onfocus = proxy(this, this.setActive);
						log("slave " + this.id + " launched!")
					};
					Slave.prototype = {
						genID : function() {
							this.id = "slid_" + +new Date % 1e3 + "_"
									+ Math.round(Math.random() * 100)
						},
						masterMonitor : function() {
							if (masters[this.nameAccount]) {
								return
							}
							log("monitoring mater state");
							var lastMasterHeartbeat = this.storage
									.get(MASTER_HEARTBEATS) || 0, gap = +new Date
									- parseInt(lastMasterHeartbeat);
							log("gap of master is " + gap);
							if (gap > 3 * MASTER_HEATBEAT_GAP) {
								this.recoverMaster()
							}
						},
						recoverMaster : function() {
							masters[this.nameAccount] = new Master(
									this.nameAccount, this.uid, this.config);
							log("recover master by slave " + this.id)
						},
						inviteMonitor : function() {
							if (this.isInvited()) {
								this.kill()
							} else if (this.isInviting()) {
								if (this.isActive()) {
									this.invite()
								}
							}
							log("slave " + this.id + " monitoring invite state")
						},
						kill : function() {
							this.monitors.invite.drop();
							this.heartBeat.drop();
							var storage = this.storage, keys = [ this.id ];
							for (var i = 0, key; key = keys[i++];) {
								storage.del(key)
							}
							log("slave " + this.id + " killed")
						},
						invite : function() {
							var kfext = this.storage.get(INVITE_KFEXT);
							var params = {
								wty : WPA_TYPE_NORMAL,
								nameAccount : this.nameAccount,
								kfuin : this.config.kfuin,
								type : WPA_STYLE_TYPE_INVITE,
								aty : kfext ? kfext === INVITE_KFEXT_AUTO ? APPOINTED_TYPE_AUTO_INVITE
										: APPOINTED_TYPE_INVITE
										: APPOINTED_TYPE_AUTO_INVITE,
								a : kfext || "",
								iv : IS_INVITE_WPA_TRUE,
								fsty : WPA_FLOAT_TYPE_FIXED,
								fposX : WPA_FLOAT_POSITION_X_CENTER,
								fposY : WPA_FLOAT_POSITION_Y_CENTER,
								sv : SESSION_VERSION_TA,
								uid : this.uid,
								dm : domain.topDomain,
								msg : this.storage.get(INVITE_MSG)
							};
							wpaMgr.invite(params, this.config.di);
							this.storage.set(INVITE_SIGNAL,
									INVITE_SIGNAL_INVITED);
							log("invited by slave " + this.id)
						},
						heartBeatProcess : function() {
							var storage = this.storage, ids = storage
									.get(SLAVE_IDS);
							if (!ids) {
								storage.set(SLAVE_IDS, this.id + "|")
							} else if (ids.indexOf(this.id + "|") === -1) {
								storage.set(SLAVE_IDS, this.id + "|" + ids)
							}
							storage.set(this.id, +new Date)
						},
						setActive : function() {
							var storage = this.storage, ids = storage
									.get(SLAVE_IDS)
									|| "", sign = this.id + DATA_SEPERATOR;
							if (ids.indexOf(this.id) > -1) {
								ids = ids.replace(sign, "")
							}
							ids += sign;
							storage.set(SLAVE_IDS, ids)
						},
						isActive : function() {
							var slaves = this.storage.get(SLAVE_IDS);
							if (!slaves) {
								return false
							}
							return slaves.substr(0, slaves.length - 1).split(
									DATA_SEPERATOR).pop() === this.id
						},
						isInvited : function() {
							return this.storage.get(INVITE_SIGNAL) === INVITE_SIGNAL_INVITED
						},
						isInviting : function() {
							return this.storage.get(INVITE_SIGNAL) === INVITE_SIGNAL_INVITE
						}
					};
					var masters = {};
					var Master = function(nameAccount, uid, cfg) {
						this.nameAccount = nameAccount;
						this.uid = uid;
						this.config = cfg;
						this.storage = blockStorage(nameAccount);
						this.genID();
						this.sleep = false;
						this.heartBeatURl = cfg.hbDomain || HEARTBEAT_URL;
						this.storage.set(MASTER_ID, this.id);
						this.heartBeatProcess();
						this.heartBeat = taskMgr.newTask(
								proxy(this, this.heartBeatProcess),
								MASTER_HEATBEAT_GAP).run();
						this.initWithConfig();
						log("master launched!")
					};
					Master.prototype = {
						genID : function() {
							this.id = +new Date % 1e3 + "_"
									+ Math.round(Math.random() * 100)
						},
						setInviteState : function(signal, kfext, msg) {
							if (signal === INVITE_SIGNAL_INVITE) {
								this.storage.set(INVITE_KFEXT, kfext);
								this.storage.set(INVITE_MSG, msg)
							}
							this.storage.set(INVITE_SIGNAL, signal)
						},
						isInvited : function() {
							var invited = this.storage.get(INVITE_SIGNAL) === INVITE_SIGNAL_INVITED;
							if (invited) {
								this.recycle();
								this.isInvited = function() {
									return true
								}
							}
							return invited
						},
						initWithConfig : function() {
							var cfg = this.config;
							if (cfg.r !== RESULT_SUCCESS) {
								this.storage.set(MASTER_HEARTBEATS,
										MASTER_HEARTBEATS_ERROR);
								return
							}
							if (cfg.isAuto === AUTO_INVITE_TRUE) {
								this.storage.set(INVITE_MSG, cfg.autoMsg);
								this.autoInviteTimer = setTimeout(proxy(this,
										function() {
											this.autoInvite()
										}), cfg.autoTime * 1e3)
							}
							this.monitors = {
								slave : taskMgr.newTask(
										proxy(this, this.slaveMonitor),
										SLAVE_HEARTBEAT_GAP).run(),
								server : taskMgr.newTask(
										proxy(this, this.serverMonitor),
										SERVER_MONITOR_GAP_MIN).run(),
								sleep : taskMgr.newTask(
										proxy(this, this.sleepMonitor),
										SERVER_MONITOR_SLEEPCHECK_GAP).run()
							};
							log("master inited with config")
						},
						autoInvite : function() {
							if (this.isInvited()) {
								return
							}
							var opt = {
								nameAccount : this.nameAccount,
								uid : this.uid
							};
							var serverMonitor = this.monitors.server;
							serverMonitor.pause();
							getJSONP(CONFIRM_AUTO_INVITE_URL, opt, proxy(this,
									function(rs) {
										if (rs.r !== RESULT_SUCCESS) {
											serverMonitor.run();
											return
										}
										if (!this.isInvited()) {
											this.setInviteState(
													INVITE_SIGNAL_INVITE,
													INVITE_KFEXT_AUTO,
													this.storage
															.get(INVITE_MSG));
											taskMgr.once(function() {
												serverMonitor.run()
											}, 5e3).run()
										}
									}))
						},
						ajustServerMonitorGap : function(time) {
							this.monitors.server.setGap(Math.min(Math.max(
									SERVER_MONITOR_GAP_MIN, time),
									SERVER_MONITOR_GAP_MAX))
						},
						serverMonitor : function() {
							var inviteSignal = this.storage.get(INVITE_SIGNAL);
							if (this.sleep) {
								return
							}
							var opt = {
								nameAccount : this.nameAccount,
								uid : this.uid
							};
							if (inviteSignal === INVITE_SIGNAL_INVITE) {
								opt["inviteState"] = INVITE_STATE_INVITE
							}
							if (inviteSignal === INVITE_SIGNAL_INVITED) {
								opt["inviteState"] = INVITE_STATE_INVITED
							}
							getJSONP(
									this.heartBeatURl,
									opt,
									proxy(
											this,
											function(rs) {
												if (rs.r !== RESULT_SUCCESS) {
													return
												}
												if (rs.gap) {
													this
															.ajustServerMonitorGap(rs.gap * 1e3)
												}
												if (rs.inviteState === INVITE_STATE_UNINVITED) {
													return
												}
												if (rs.inviteState === INVITE_STATE_INVITE) {
													this
															.setInviteState(
																	INVITE_SIGNAL_INVITE,
																	rs.kfext,
																	rs.inviteMsg);
													return
												}
												if (rs.inviteState === INVITE_STATE_INVITED) {
													this
															.setInviteState(INVITE_SIGNAL_INVITED)
												}
											}))
						},
						slaveMonitor : function() {
							if (this.isInvited()) {
								this.monitors.slave.drop()
							}
							var storage = this.storage, slaves = storage
									.get(SLAVE_IDS);
							if (!slaves) {
								return
							}
							slaves = slaves.split(DATA_SEPERATOR);
							var aliveSlaves = "", time = +new Date, lastSlaveHeartbeat, slave, gap;
							for (var i = 0; slave = slaves[i++];) {
								log("monitoring slave " + slave + " state");
								lastSlaveHeartbeat = storage.get(slave) || 0;
								gap = time - parseInt(lastSlaveHeartbeat);
								log("gap of slave " + slave + " is " + gap);
								if (gap > 3 * SLAVE_HEARTBEAT_GAP) {
									storage.del(slave);
									log("clear slave " + slave + " in storage")
								} else {
									aliveSlaves += slave + DATA_SEPERATOR
								}
							}
							storage.set(SLAVE_IDS, aliveSlaves)
						},
						sleepMonitor : function() {
							var slaves = this.storage.get(SLAVE_IDS) || "", activeSlave = slaves
									.substr(0, slaves.length - 1).split(
											DATA_SEPERATOR).pop();
							if (this.sleep) {
								if (this.activeSlave !== activeSlave) {
									this.activeSlave = activeSlave;
									this.sleep = false;
									this.monitors.sleep
											.setGap(SERVER_MONITOR_SLEEPCHECK_GAP)
								}
							} else {
								if (this.activeSlave === activeSlave) {
									this.sleep = true;
									this.monitors.sleep
											.setGap(SERVER_MONITOR_SLEEPING_GAP)
								} else {
									this.activeSlave = activeSlave
								}
							}
						},
						kill : function() {
							masters[this.nameAccount] = undefined;
							if (this.monitors) {
								this.monitors.server.drop();
								this.monitors.slave.drop();
								this.heartBeat.drop();
								clearTimeout(this.autoInviteTimer)
							}
							log("master killed")
						},
						recycle : function() {
							var storage = this.storage, keys = [ INVITE_KFEXT,
									INVITE_MSG ];
							for (var i = 0, key; key = keys[i++];) {
								storage.del(key)
							}
							log("storage recycled")
						},
						heartBeatProcess : function() {
							var storage = this.storage;
							if (storage.get(MASTER_ID) !== this.id) {
								this.kill();
								return false
							}
							this.storage.set(MASTER_HEARTBEATS, +new Date)
						}
					};
					var slaves = {};
					return {
						load : function(nameAccount, uid, cfg) {
							if (this.isLoaded(nameAccount)) {
								log(nameAccount + " slave already running");
								return
							}
							var slave = new Slave(nameAccount, uid, cfg);
							slaves[nameAccount] ? slaves[nameAccount]
									.push(slave)
									: slaves[nameAccount] = [ slave ]
						},
						isLoaded : function(nameAccount) {
							return typeof slaves[nameAccount] !== "undefined"
						}
					}
				});
BizQQWPA
		.define(
				"util.taskMgr",
				"util.proxy",
				function(require) {
					var TASK_RUN = "run", TASK_PAUSE = "pause", TASK_DROP = "drop", LOOP_TIME = 50;
					var proxy = require("proxy");
					var TM = function() {
						this.circle = [];
						this.pos = 0;
						setInterval(proxy(this, this.loop), 16)
					};
					TM.prototype = {
						newTask : function(fn, gap) {
							var t = new Task(fn, gap);
							this.circle.push(t);
							return t
						},
						once : function(fn, gap) {
							return this.newTask(function() {
								fn.apply(this);
								this.drop()
							}, gap)
						},
						loop : function() {
							var c = this.circle, pos = this.pos, count = c.length, start = +new Date, loopTime = LOOP_TIME, t = c[pos];
							while (count > 0 && +new Date - start < loopTime) {
								if (t.isRunning()) {
									t.execute()
								} else if (t.isDropped()) {
									c.splice(pos, 1);
									pos--
								}
								pos = (pos + 1) % c.length;
								t = c[pos];
								count--
							}
							this.pos = pos
						}
					};
					var Task = function(fn, gap) {
						this.fn = fn;
						this.gap = gap;
						this.status = TASK_PAUSE;
						this.lastExecTime = +new Date
					};
					Task.prototype = {
						run : function() {
							this.status = TASK_RUN;
							return this
						},
						pause : function() {
							this.status = TASK_PAUSE;
							return this
						},
						drop : function() {
							this.status = TASK_DROP;
							return this
						},
						execute : function() {
							if (+new Date - this.lastExecTime < this.gap) {
								return false
							}
							this.fn();
							this.lastExecTime = +new Date;
							return true
						},
						getGap : function() {
							return this.gap
						},
						setGap : function(newGap) {
							this.gap = newGap;
							return this
						},
						isRunning : function() {
							return this.status === TASK_RUN
						},
						isPaused : function() {
							return this.status === TASK_PAUSE
						},
						isDropped : function() {
							return this.status === TASK_DROP
						}
					};
					return new TM
				});
BizQQWPA
		.define(
				"lang.browser",
				function() {
					var ua = navigator.userAgent.toLowerCase();
					var browser = {};
					var match = /(chrome)[ \/]([\w.]+)/.exec(ua)
							|| /(webkit)[ \/]([\w.]+)/.exec(ua)
							|| /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua)
							|| /(msie) ([\w.]+)/.exec(ua)
							|| ua.indexOf("compatible") < 0
							&& /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
					var matchIe11;
					if (ua.indexOf("trident") > -1
							&& (matchIe11 = /rv:([\d.]+)/.exec(ua))) {
						match[1] = "msie";
						match[2] = matchIe11[1]
					}
					var matched = {
						browser : match[1] || "",
						version : match[2] || "0"
					};
					if (matched.browser) {
						browser[matched.browser] = true;
						browser.version = matched.version
					}
					if (browser.chrome) {
						browser.webkit = true
					} else if (browser.webkit) {
						browser.safari = true
					}
					var isMobile = browser.isMobile = ua
							.match(/(nokia|iphone|android|motorola|^mot\-|softbank|foma|docomo|kddi|up\.browser|up\.link|htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam\-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte\-|longcos|pantech|gionee|^sie\-|portalmmm|jig\s browser|hiptop|^ucweb|^benq|haier|^lct|opera\s*mobi|opera\*mini|320x320|240x320|176x220)/i);
					browser.isWindow = /windows|win32/.test(ua);
					browser.isMac = /Mac/.test(ua);
					browser.isIOS = /(?:iphone|ipad|ipod)/i.test(ua);
					browser.isAndroid = /android/i.test(ua);
					if (isMobile) {
						var QQReg = /QQ\/(\d+\.\d+)\.\d/, OldQQReg = /V1_AND_SQ_(\d+\.\d+)\.\d/, match = QQReg
								.exec(ua)
								|| OldQQReg.exec(ua);
						browser.isQQ = !match;
						match && (browser.QQVersion = match[1])
					}
					return browser
				});
BizQQWPA.define("util.pad", function() {
	return function(str, pad, length, isLeft) {
		var padLength = length - str.length, i;
		if (isLeft === false) {
			for (i = 0; i < padLength; i++) {
				str += pad
			}
		} else {
			for (i = 0; i < padLength; i++) {
				str = pad + str
			}
		}
		return str
	}
});
BizQQWPA.define("util.Bits", "util.proxy,util.pad", function(require) {
	var proxy = require("proxy"), pad = require("pad");
	return function() {
		var setChar = function(str, index, newChar) {
			return str.replace(new RegExp("(^[\\d]{" + index + "})\\d"),
					"$1#" + newChar).replace("#", "")
		};
		var Bits = function(bits) {
			this.bits = bits
		};
		Bits.prototype = {
			pad : function() {
				var args = Array.prototype.slice.call(arguments);
				this.bits = pad.apply(this, [ this.bits ].concat(args));
				return this
			},
			padLeft : function() {
				return proxy(this, this.pad)
			},
			padRight : function() {
				var args = Array.prototype.slice.call(arguments).push(false);
				return this.pad.apply(this, args)
			},
			getChar : function(index) {
				return this.bits.charAt(index)
			},
			setChar : function(index, value) {
				this.bits = setChar(this.bits, index, value);
				return this
			},
			reverse : function() {
				var bits = this.bits, length = bits.length;
				for (var i = 0; i < length; i++) {
					this.setChar(i, parseInt(bits[i], 2) ^ 1)
				}
				return this
			}
		};
		return Bits
	}()
});
BizQQWPA.define("util.events", function() {
	var events = {};
	events.addEvent = window.addEventListener ? function(node, type, event) {
		node.addEventListener(type, event);
		return node
	} : function(node, type, event) {
		node.attachEvent("on" + type, event);
		return node
	};
	events.removeEvent = window.removeEventListener ? function(node, type,
			event) {
		node.removeEventListener(type, event);
		return node
	} : function(node, type, event) {
		node.detachEvent("on" + type, event);
		return node
	};
	return events
});
BizQQWPA.define("util.onLoad", "util.events", function(require) {
	var events = require("events");
	return onLoad = function(fn, context) {
		context = context || window;
		if (/loaded|complete|undefined/.test(context.document.readyState)) {
			fn()
		} else {
			events.addEvent(context, "load", fn)
		}
		return context
	}
});
BizQQWPA
		.define(
				"util.offset",
				function() {
					var doc = document, isStandardMode = doc.compatMode == "CSS1Compat", docElem = doc.documentElement, body = doc.body;
					return {
						getScrollTop : function() {
							return Math.max(docElem.scrollTop, body.scrollTop)
						},
						getClientWidth : function() {
							return isStandardMode ? docElem.clientWidth
									: body.clientWidth
						},
						getClientHeight : function() {
							return isStandardMode ? docElem.clientHeight
									: body.clientHeight
						}
					}
				});
BizQQWPA
		.define(
				"util.Panel",
				"lang.browser,util.Style,util.className,util.events,util.offset,util.css,util.proxy",
				function(require) {
					var Style = require("Style"), className = require("className"), events = require("events"), offset = require("offset"), browser = require("browser"), css = require("css"), proxy = require("proxy");
					var SETTINGS = {
						container : document.getElementsByTagName("body")[0],
						template : [
								'<div class="WPA3-CONFIRM">',
								'<h3 class="WPA3-CONFIRM-TITLE"><%=title%></h3>',
								'<div class="WPA3-CONFIRM-CONTENT"><%=content%></div>',
								'<div class="WPA3-CONFIRM-PANEL"><%=buttons%></div>',
								'<div class="WPA3-CONFIRM-CLOSE"></div>',
								"</div>" ].join(""),
						buttonTemplate : [ '<a href="javascript:;" class="WPA3-CONFIRM-BUTTON"><span class="WPA3-CONFIRM-BUTTON-PADDING WPA3-CONFIRM-BUTTON-LEFT"></span><span class="WPA3-CONFIRM-BUTTON-TEXT"><%=text%></span><span class="WPA3-CONFIRM-BUTTON-PADDING WPA3-CONFIRM-BUTTON-RIGHT"></span></a>' ]
								.join(""),
						cssText : [
								".WPA3-CONFIRM { z-index:2147483647; width:285px; height:141px; margin:0; background:url() no-repeat;}",
								".WPA3-CONFIRM { *background-image:url(http://combo.b.qq.com/crm/wpa/release/3.3/wpa/views/panel.png);}",
								'.WPA3-CONFIRM * { position:static; z-index:auto; top:auto; left:auto; right:auto; bottom:auto; width:auto; height:auto; max-height:auto; max-width:auto; min-height:0; min-width:0; margin:0; padding:0; border:0; clear:none; clip:auto; background:transparent; color:#333; cursor:auto; direction:ltr; filter:; float:none; font:normal normal normal 12px "Helvetica Neue", Arial, sans-serif; line-height:16px; letter-spacing:normal; list-style:none; marks:none; overflow:visible; page:auto; quotes:none; -o-set-link-source:none; size:auto; text-align:left; text-decoration:none; text-indent:0; text-overflow:clip; text-shadow:none; text-transform:none; vertical-align:baseline; visibility:visible; white-space:normal; word-spacing:normal; word-wrap:normal; -webkit-box-shadow:none; -moz-box-shadow:none; -ms-box-shadow:none; -o-box-shadow:none; box-shadow:none; -webkit-border-radius:0; -moz-border-radius:0; -ms-border-radius:0; -o-border-radius:0; border-radius:0; -webkit-opacity:1; -moz-opacity:1; -ms-opacity:1; -o-opacity:1; opacity:1; -webkit-outline:0; -moz-outline:0; -ms-outline:0; -o-outline:0; outline:0; -webkit-text-size-adjust:none;}',
								".WPA3-CONFIRM * { font-family:Microsoft YaHei,Simsun;}",
								".WPA3-CONFIRM .WPA3-CONFIRM-TITLE { height:40px; margin:0; padding:0; line-height:40px; color:#2b6089; font-weight:normal; font-size:14px; text-indent:80px;}",
								".WPA3-CONFIRM .WPA3-CONFIRM-CONTENT { height:55px; margin:0; line-height:55px; color:#353535; font-size:14px; text-indent:29px;}",
								".WPA3-CONFIRM .WPA3-CONFIRM-PANEL { height:30px; margin:0; padding-right:16px; text-align:right;}",
								".WPA3-CONFIRM .WPA3-CONFIRM-BUTTON { position:relative; display:inline-block!important; display:inline; zoom:1; width:99px; height:30px; margin-left:10px; line-height:30px; color:#000; text-decoration:none; font-size:12px; text-align:center;}",
								".WPA3-CONFIRM .WPA3-CONFIRM-BUTTON-FOCUS { width:78px;}",
								".WPA3-CONFIRM .WPA3-CONFIRM-BUTTON .WPA3-CONFIRM-BUTTON-TEXT { line-height:30px; text-align:center; cursor:pointer;}",
								".WPA3-CONFIRM-CLOSE { position:absolute; top:7px; right:7px; width:10px; height:10px; cursor:pointer;}" ]
								.join(""),
						buttons : [ {
							isFocus : true,
							text : "确认",
							events : {
								click : function() {
									this.remove()
								}
							}
						}, {
							text : "取消",
							events : {
								click : function() {
									this.remove()
								}
							}
						} ],
						modal : true
					};
					Style.add("_WPA_CONFIRM_STYLE", SETTINGS.cssText);
					var Panel = function(opts) {
						this.opts = opts;
						this.render()
					};
					Panel.prototype = {
						render : function() {
							var panel = this, opts = this.opts, body = this.container = opts.container
									|| document.getElementsByTagName("body")[0];
							var frameHTML = opts.template || SETTINGS.template, buttonReplaceID = "WPA_BUTTONS_PLACE"
									+ +new Date
									% 100
									+ Math.floor(Math.random() * 100);
							frameHTML = frameHTML.replace(/<%=title%>/g,
									opts.title || "").replace(/<%=content%>/g,
									opts.content || "").replace(
									/<%=buttons%>/g,
									'<div id="' + buttonReplaceID + '"></div>');
							var frag = document.createElement("div"), frame;
							frag.innerHTML = frameHTML;
							this.$el = frame = frag.firstChild;
							events.addEvent(frame.lastChild, "click",
									function() {
										panel.remove();
										opts.onClose && opts.onClose()
									});
							(function() {
								try {
									body.appendChild(frame)
								} catch (e) {
									setTimeout(arguments.callee, 1);
									return
								}
								if (opts.modal || SETTINGS.modal) {
									panel.renderModal()
								}
								panel.renderButtons(buttonReplaceID);
								panel.setCenter()
							})()
						},
						renderButtons : function(buttonReplaceID) {
							var replaceElement = document
									.getElementById(buttonReplaceID), parentNode = replaceElement.parentNode;
							parentNode.removeChild(replaceElement);
							var buttonOpts = this.opts.buttons
									|| SETTINGS.buttons, buttonTempl = this.opts.buttonTemplate
									|| SETTINGS.buttonTemplate, frag = document
									.createElement("div"), button, opt, evts;
							for (var i = 0, l = buttonOpts.length; i < l; i++) {
								opt = buttonOpts[i];
								frag.innerHTML = buttonTempl.replace(
										"<%=text%>", opt.text);
								button = frag.firstChild;
								opt.isFocus
										&& className.addClass(button,
												"WPA3-CONFIRM-BUTTON-FOCUS");
								if (opt.events) {
									evts = opt.events;
									for ( var type in evts) {
										if (evts.hasOwnProperty(type)) {
											events.addEvent(button, type,
													proxy(this, evts[type]))
										}
									}
								}
								parentNode.appendChild(button)
							}
						},
						renderModal : function() {
							var container = this.container, width = css(
									container, "width"), height = css(
									container, "height"), overflow = css(
									container, "overflow");
							var modalLayer = document.createElement("div"), styles = {
								position : "fixed",
								top : 0,
								left : 0,
								zIndex : 2147483647,
								width : offset.getClientWidth() + "px",
								height : offset.getClientHeight() + "px",
								backgroundColor : "black",
								opacity : .3,
								filter : "alpha(opacity=30)"
							};
							var isQuirk = document.compatMode === "BackCompat";
							if (browser.msie
									&& parseInt(browser.version, 10) < 7
									|| isQuirk) {
								styles.position = "absolute";
								setInterval(proxy(modalLayer, function() {
									this.style.top = offset.getScrollTop()
											+ "px"
								}), 128)
							}
							css(modalLayer, styles);
							container.insertBefore(modalLayer, this.$el);
							this.modal = modalLayer;
							events.addEvent(window, "resize", proxy(modalLayer,
									function() {
										css(this, {
											width : offset.getClientWidth()
													+ "px",
											height : offset.getClientHeight()
													+ "px"
										})
									}))
						},
						show : function() {
							this.css("display", "block");
							this.modal && css(this.modal, "display", "block");
							return this
						},
						hide : function() {
							this.css("display", "none");
							this.modal && css(this.modal, "display", "none");
							return this
						},
						remove : function() {
							this.$el.parentNode.removeChild(this.$el);
							this.modal
									&& this.modal.parentNode
											.removeChild(this.modal);
							return this
						},
						css : function() {
							var args = [ this.$el ]
									.concat(Array.prototype.slice
											.call(arguments));
							return css.apply(this, args)
						},
						setCenter : function() {
							this.css({
								position : "absolute",
								top : "50%",
								left : "50%"
							});
							var styles = {
								position : "fixed",
								marginLeft : "-" + this.outerWidth() / 2 + "px",
								marginTop : "-" + this.outerHeight() / 2 + "px"
							};
							var isQuirk = document.compatMode === "BackCompat";
							if (browser.msie
									&& parseInt(browser.version, 10) < 7
									|| isQuirk) {
								styles.position = "absolute";
								styles.marginTop = 0;
								var top = styles.top = (offset
										.getClientHeight() - this.outerHeight()) / 2;
								setInterval(proxy(this.$el, function() {
									this.style.top = offset.getScrollTop()
											+ top + "px"
								}), 128)
							}
							this.css(styles)
						},
						outerWidth : function() {
							return this.$el.offsetWidth
						},
						outerHeight : function() {
							return this.$el.offsetHeight
						}
					};
					return Panel
				});